using System;
using System.Collections.Generic;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using TTDotNet.Engine.Terrain;

namespace TTDotNet.Engine.ThreeDEngine
{
    public class TileMapStrip : AJObject
    {

        private short gridWidth;
        private short gridLength;

        private int primitives;

        private GameTexture grassTexture;

        private VertexBuffer vertexBuffer;
        private CustomVertex.PositionTextured[] vertices;
        private IndexBuffer indexBuffer;
        private int[] gridIndices;

        public TileMapStrip(int width, int length)
        {
            gridWidth = (short)width;
            gridLength = (short)length;

            grassTexture = Game.textureCacher.LoadTexture("artwork/512/grassNewC.jpg");

            BuildGrid();
        }

        private void BuildGrid()
        {
            primitives = ((gridWidth * gridLength * 2) + (gridWidth * 3));

            BuildFourTriangleVB();
        }

        public void AddTiles(Tile[,] tiles)
        {
            int num = 0;
            
            //gridIndices = new int[gridWidth * gridLength * 12];
            //gridIndices = new int[(((gridWidth * 3) + 1) * gridLength) + 1];
            gridIndices = new int[(gridWidth * gridLength * 2) + (gridLength * 4) - 2];

            //int x = 0;
            //int z = 0;

            for (int z = 0; z < gridLength; z++)
            {
                gridIndices[num++] = z * (gridWidth + 1);
                gridIndices[num++] = (z + 1) * (gridWidth + 1);

                for (int x = 0; x < gridWidth; x++)
                {
                    gridIndices[num++] = (z * (gridWidth + 1)) + 1 + x;
                    gridIndices[num++] = (z + 1) * (gridWidth + 1) + 1 + x;
                }

                if(z != (gridLength - 1)) {
                    gridIndices[num++] = (z + 1) * (gridWidth + 1) + gridWidth;
                    gridIndices[num++] = (z + 1) * (gridWidth + 1);
                }
                
                

            }

            

            //for (int i = 0; i < gridWidth * gridLength; i++)
            //{
            //    int se = (z * (((gridWidth + 1) * 2) - 1)) + x + 1;
            //    int sw = (z * (((gridWidth + 1) * 2) - 1)) + x;
            //    int nw = (z * (((gridWidth + 1) * 2) - 1)) + x + ((gridWidth + 1) * 2) - 1;
            //    int ne = (z * (((gridWidth + 1) * 2) - 1)) + x + ((gridWidth + 1) * 2);
            //    int cen = (z * (((gridWidth + 1) * 2) - 1)) + (gridWidth + 1) + x;

            //    //Console.WriteLine("X = " + x + " , Z = " + z);

            //    //if (x > 10)
            //    //{
            //    //    Console.WriteLine("stop");

            //    //}

            //    if (x % 2 == 0)
            //    {
            //        if (z % 2 == 0)
            //        {
            //            gridIndices[num++] = nw; //W
            //            gridIndices[num++] = sw; //W
            //            gridIndices[num++] = cen; //W

            //            gridIndices[num++] = sw; //S
            //            gridIndices[num++] = se; //S
            //            gridIndices[num++] = cen; //S

            //            gridIndices[num++] = se; //E
            //            gridIndices[num++] = ne; //E
            //            gridIndices[num++] = cen; //E

            //            gridIndices[num++] = ne; //N
            //            gridIndices[num++] = nw; //N
            //            gridIndices[num++] = cen; //N
            //            z++;
            //        }
            //        else
            //        {
            //            gridIndices[num++] = sw; //S
            //            gridIndices[num++] = se; //S
            //            gridIndices[num++] = cen; //S

            //            gridIndices[num++] = nw; //W
            //            gridIndices[num++] = sw; //W
            //            gridIndices[num++] = cen; //W

            //            gridIndices[num++] = ne; //N
            //            gridIndices[num++] = nw; //N
            //            gridIndices[num++] = cen; //N

            //            gridIndices[num++] = se; //E
            //            gridIndices[num++] = ne; //E
            //            gridIndices[num++] = cen; //E
            //            x++;
            //        }
            //    }
            //    else
            //    {
            //        if (z % 2 == 0)
            //        {
            //            gridIndices[num++] = ne; //N
            //            gridIndices[num++] = nw; //N
            //            gridIndices[num++] = cen; //N

            //            gridIndices[num++] = nw; //W
            //            gridIndices[num++] = sw; //W
            //            gridIndices[num++] = cen; //W

            //            gridIndices[num++] = sw; //S
            //            gridIndices[num++] = se; //S
            //            gridIndices[num++] = cen; //S

            //            gridIndices[num++] = se; //E
            //            gridIndices[num++] = ne; //E
            //            gridIndices[num++] = cen; //E

            //            if (x + 1 != gridWidth)
            //            {
            //                x++;
            //            }
            //            else
            //            {
            //                x = 0;
            //                z += 2;
            //            }
            //        }
            //        else
            //        {
            //            gridIndices[num++] = nw; //W
            //            gridIndices[num++] = sw; //W
            //            gridIndices[num++] = cen; //W

            //            gridIndices[num++] = ne; //N
            //            gridIndices[num++] = nw; //N
            //            gridIndices[num++] = cen; //N

            //            gridIndices[num++] = se; //E
            //            gridIndices[num++] = ne; //E
            //            gridIndices[num++] = cen; //E

            //            gridIndices[num++] = sw; //S
            //            gridIndices[num++] = se; //S
            //            gridIndices[num++] = cen; //S
            //            z--;
            //        }
            //    }
            //}

            //gridIndices[num++] = 0;

            //for (int i = 0; i < gridWidth * gridLength; i++)
            //{
            //    int se = (z * (((gridWidth + 1) * 2) - 1)) + x + 1;
            //    int sw = (z * (((gridWidth + 1) * 2) - 1)) + x;
            //    int nw = (z * (((gridWidth + 1) * 2) - 1)) + x + ((gridWidth + 1) * 2) - 1;
            //    int ne = (z * (((gridWidth + 1) * 2) - 1)) + x + ((gridWidth + 1) * 2);
            //    int cen = (z * (((gridWidth + 1) * 2) - 1)) + (gridWidth + 1) + x;

            //    if (x % 2 == 0)
            //    {
            //        if (z % 2 == 0)
            //        {
            //            if (x == 0)
            //            {
            //                gridIndices[num++] = nw;
            //            }

            //            gridIndices[num++] = cen;
            //            gridIndices[num++] = ne;
            //            gridIndices[num++] = se;

            //            x++;
            //        }
            //        else
            //        {
            //            gridIndices[num++] = cen;
            //            gridIndices[num++] = sw;
            //            gridIndices[num++] = nw;

            //            if (x == 0)
            //            {
            //                z++;
            //            }
            //            else
            //            {
            //                x--;
            //            }
            //        }
            //    }
            //    else
            //    {
            //        if (z % 2 == 0)
            //        {
            //            gridIndices[num++] = cen;
            //            gridIndices[num++] = se;
            //            gridIndices[num++] = ne;

            //            if (x + 1 == gridWidth)
            //            {
            //                z++;
            //            }
            //            else
            //            {
            //                x++;
            //            }
            //        }
            //        else
            //        {
            //            if (x + 1 == gridWidth)
            //            {
            //                gridIndices[num++] = ne;
            //            }

            //            gridIndices[num++] = cen;
            //            gridIndices[num++] = nw;
            //            gridIndices[num++] = sw;

            //            x--;
            //        }
            //    }
            //}

            indexBuffer = new IndexBuffer(typeof(int), num, Game.device, Usage.WriteOnly, Pool.Default);

            indexBuffer.SetData(gridIndices, 0, LockFlags.None);

            Game.device.SamplerState[0].MagFilter = TextureFilter.Anisotropic;
            Game.device.SamplerState[0].MaxAnisotropy = 16;

            Game.device.SamplerState[0].MinFilter = TextureFilter.Anisotropic;
            Game.device.SamplerState[0].MipFilter = TextureFilter.Anisotropic;
        }

        private void BuildFourTriangleVB()
        {
            //vertices = new CustomVertex.PositionTextured[((gridWidth + 1) * (gridLength + 1)) + (gridWidth * gridLength)];
            vertices = new CustomVertex.PositionTextured[((gridWidth + 1) * (gridLength + 1))];

            int num = 0;

            for (int z = 0; z < gridLength + 1; z++)
            {
                for (int x = 0; x < gridWidth + 1; x++)
                {
                    vertices[num] = new CustomVertex.PositionTextured((x - 0.5f), 0, (z - 0.5f), 0, 0);

                    if (x % 2 == 0)
                    {
                        if (z % 2 == 0)
                        {
                            vertices[num].Tu = 0;
                            vertices[num].Tv = 1;
                        } else {
                            vertices[num].Tu = 0;
                            vertices[num].Tv = 0;
                        }
                    }
                    else
                    {
                        if (z % 2 == 0)
                        {
                            vertices[num].Tu = 1;
                            vertices[num].Tv = 1;
                        } else {
                            vertices[num].Tu = 1;
                            vertices[num].Tv = 0;
                        }
                    }
                    num++;
                }

                //if (z != gridLength)
                //{
                //    for (int x = 0; x < gridWidth; x++)
                //    {
                //        vertices[num++] = new CustomVertex.PositionTextured(x, 0, z, 0.5f, 0.5f);
                //    }
                //}
            }

            BuildVertexBuffer();

        }

        private void BuildVertexBuffer()
        {
            vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionTextured), vertices.Length, Game.device, Usage.None,
                                            CustomVertex.PositionTextured.Format, Pool.Default);

            vertexBuffer.SetData(vertices, 0, LockFlags.None);
        }

        public override void Render(AJCamera camera)
        {
            Game.device.RenderState.Lighting = false;

            Game.device.Transform.Projection = camera.Projection;
            Game.device.VertexFormat = CustomVertex.PositionTextured.Format;
            Game.device.RenderState.CullMode = Cull.None;

            Game.device.SetStreamSource(0, vertexBuffer, 0);

            Game.device.Indices = indexBuffer;

            Game.device.SetTexture(0, grassTexture.Texture);

            Game.device.DrawIndexedPrimitives(PrimitiveType.TriangleStrip, 0, 0, vertices.Length, 0, (gridIndices.Length - 2));
            Game.device.DrawIndexedPrimitives(PrimitiveType.TriangleStrip, 0, 0, vertices.Length, 0, (gridIndices.Length - 2));
        }
    }
}
